<template>
  <main class="main-content">
    <div class="breadcrumb">
      <span class="breadcrumb-item">设备管理</span>
      <span class="breadcrumb-separator">/</span>
      <span class="breadcrumb-item active">位置管理</span>
    </div>

    <div class="card">
      <div class="table-actions-bar">
        <a-button type="primary" @click="handleAddRoot">
          <template #icon><PlusOutlined /></template>
          新增根位置
        </a-button>
        <a-input-search
          v-model:value="searchValue"
          style="width: 250px"
          placeholder="输入位置名称过滤"
          allow-clear
        />
      </div>

      <a-spin :spinning="loading">
        <a-table
          :columns="columns"
          :data-source="filteredTreeData"
          :pagination="false"
          row-key="id"
          bordered
          :default-expand-all-rows="true"
        >
          <template #bodyCell="{ column, record, index }">
            <template v-if="column.key === 'sortOrder'">
              <a-space direction="vertical" :size="4">
                <a-tooltip title="上移">
                  <a-button 
                    type="text" 
                    size="small" 
                    :disabled="index === 0"
                    @click="handleMoveSort(record, 'up')"
                  >
                    <template #icon><ArrowUpOutlined /></template>
                  </a-button>
                </a-tooltip>
                <a-tooltip title="下移">
                  <a-button 
                    type="text" 
                    size="small" 
                    :disabled="index === (findSiblings(record).length - 1)"
                    @click="handleMoveSort(record, 'down')"
                  >
                    <template #icon><ArrowDownOutlined /></template>
                  </a-button>
                </a-tooltip>
              </a-space>
            </template>
            
            <template v-if="column.key === 'action'">
              <a-space :size="'middle'">
                <a @click="handleAddChild(record)">新增子级</a>
                <a @click="handleEdit(record)">编辑</a>
                <a-popconfirm
                  title="确认删除此位置吗？"
                  ok-text="确认"
                  cancel-text="取消"
                  @confirm="handleDelete(record.id)"
                >
                  <a class="text-danger">删除</a>
                </a-popconfirm>
              </a-space>
            </template>
          </template>
        </a-table>
        <a-empty v-if="!loading && (!filteredTreeData || filteredTreeData.length === 0)" description="暂无数据或无匹配结果" style="margin-top: 24px;" />
      </a-spin>
    </div>

    <!-- 新增/编辑弹窗 -->
    <a-modal v-model:open="modalVisible" :title="modalTitle" @ok="handleOk" :confirm-loading="modalLoading">
      <a-form :model="formState" layout="vertical" ref="formRef">
        <a-form-item label="上级位置" v-if="isEditMode">
          <a-tree-select
            v-model:value="formState.parentId"
            style="width: 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            :tree-data="locationTreeForSelect"
            placeholder="选择新的上级位置 (留空则为根位置)"
            tree-default-expand-all
            allow-clear
            :field-names="{ children: 'children', label: 'name', value: 'id' }"
          />
        </a-form-item>
        <a-form-item label="位置名称" name="name" :rules="[{ required: true, message: '位置名称不能为空' }]">
          <a-input v-model:value="formState.name" />
        </a-form-item>
        <a-form-item label="位置描述">
          <a-textarea v-model:value="formState.description" :rows="4" />
        </a-form-item>
      </a-form>
    </a-modal>
  </main>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';
import { message } from 'ant-design-vue';
import { ArrowUpOutlined, ArrowDownOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { 
  getLocationTree, createLocation, updateLocation, deleteLocation, 
  moveLocation, updateSortOrder 
} from '@/api/locations'; 


// --- 表格列定义 ---
const columns = [
  { title: '位置名称', dataIndex: 'name', key: 'name' },
  { title: '设备数量', dataIndex: 'deviceCount', key: 'deviceCount', width: '120px', align: 'center' },
  { title: '描述', dataIndex: 'description', key: 'description' }, 
  { title: '排序', key: 'sortOrder', width: '80px', align: 'center' },
  { title: '操作', key: 'action', width: '220px', align: 'center' },
];
// --- 响应式状态 ---
const loading = ref(false);
const treeData = ref([]); 
const searchValue = ref(''); 
const formRef = ref();

// --- 弹窗相关状态 ---
const modalVisible = ref(false);
const modalLoading = ref(false);
const modalTitle = ref('');
const isEditMode = ref(false);
const initialFormState = { id: null, parentId: null, name: '', description: '' };
const formState = ref({ ...initialFormState });

// --- 数据获取与处理 ---
const fetchTreeData = async () => {
  loading.value = true;
  try {
    const response = await getLocationTree();
    treeData.value = response.data || [];
  } catch (error) {
    message.error('加载位置树失败');
    treeData.value = [];
  } finally {
    loading.value = false;
  }
};

const filteredTreeData = computed(() => {
  const keyword = searchValue.value.trim().toLowerCase();
  if (!keyword) {
    return treeData.value;
  }
  
  function filter(nodes) {
    if (!nodes || nodes.length === 0) {
      return null;
    }
    
    const newChildren = [];
    for (const node of nodes) {
      const filteredChildren = filter(node.children);
      if (node.name.toLowerCase().includes(keyword) || (filteredChildren && filteredChildren.length > 0)) {
        newChildren.push({ ...node, children: filteredChildren || [] });
      }
    }
    return newChildren.length > 0 ? newChildren : null;
  }
  
  return filter(JSON.parse(JSON.stringify(treeData.value))) || [];
});

const locationTreeForSelect = computed(() => {
  if (!isEditMode.value || !formState.value.id) return treeData.value;

  const disabledIds = new Set();
  
  // 查找并收集节点及其所有子孙节点的 ID
  const findAndCollect = (nodes, targetId) => {
    for (const node of nodes) {
      if (node.id === targetId) {
        collectIds(node);
        return true;
      }
      if (node.children && findAndCollect(node.children, targetId)) {
        return true;
      }
    }
    return false;
  };
  const collectIds = (startNode) => {
    disabledIds.add(startNode.id);
    if (startNode.children) {
      startNode.children.forEach(collectIds);
    }
  };
  
  findAndCollect(treeData.value, formState.value.id);

  // 递归地为树节点添加 disabled 属性
  const mapNodes = (node) => ({
    ...node,
    disabled: disabledIds.has(node.id),
    children: node.children ? node.children.map(mapNodes) : undefined,
  });

  return treeData.value.map(mapNodes);
});

// --- 事件处理 ---
const resetForm = () => {
  formState.value = { ...initialFormState };
};

const handleAddRoot = () => {
  resetForm();
  isEditMode.value = false;
  modalTitle.value = '新增根位置';
  modalVisible.value = true;
};

const handleAddChild = (parentNode) => {
  resetForm();
  isEditMode.value = false;
  modalTitle.value = `在“${parentNode.name}”下新增子位置`;
  formState.value.parentId = parentNode.id;
  modalVisible.value = true;
};

const handleEdit = (node) => {
  isEditMode.value = true;
  modalTitle.value = `编辑位置“${node.name}”`;
  const findParentId = (nodes, nodeId) => {
      for (const n of nodes) {
          if (n.children && n.children.some(child => child.id === nodeId)) {
              return n.id;
          }
          if (n.children) {
              const pid = findParentId(n.children, nodeId);
              if (pid !== null) return pid;
          }
      }
      return null;
  };
  formState.value = { 
    id: node.id, 
    parentId: findParentId(treeData.value, node.id),
    name: node.name, 
    description: node.description 
  };
  modalVisible.value = true;
};

const handleDelete = async (id) => {
  try {
    await deleteLocation(id);
    message.success('删除成功');
    await fetchTreeData();
  } catch (error) {
    message.error(error.response?.data?.message || '删除失败，请检查该位置下是否还有子节点或设备。');
  }
};

const handleOk = async () => {
  try {
    await formRef.value.validate();
    modalLoading.value = true;

    if (isEditMode.value) {
      const findNodeById = (nodes, id) => {
        for(const node of nodes) {
            if (node.id === id) return node;
            if (node.children) {
                const found = findNodeById(node.children, id);
                if(found) return found;
            }
        }
        return null;
      };
      const originalNode = findNodeById(treeData.value, formState.value.id);
      
      const updatePayload = {
          name: formState.value.name,
          description: formState.value.description
      };
      await updateLocation(formState.value.id, updatePayload);
      
      if (originalNode && originalNode.parentId !== formState.value.parentId) {
        await moveLocation({ dragId: formState.value.id, targetId: formState.value.parentId });
      }
      message.success('更新成功');
    } else {
      await createLocation({
        parentId: formState.value.parentId,
        name: formState.value.name,
        description: formState.value.description,
      });
      message.success('新增成功');
    }
    modalVisible.value = false;
    await fetchTreeData();
  } catch (errorInfo) {
    if (errorInfo.response) {
        message.error(errorInfo.response?.data?.message || '操作失败');
    } else {
        console.log('Form validation failed:', errorInfo);
    }
  } finally {
    modalLoading.value = false;
  }
};

const findSiblings = (node) => {
  if (node.parentId === null || node.parentId === undefined) {
    return treeData.value;
  }
  let result = null;
  function findInNodes(nodes, parentId) {
    for (const n of nodes) {
      if (n.id === parentId) {
        result = n.children || [];
        return;
      }
      if (n.children && n.children.length > 0) {
        findInNodes(n.children, parentId);
        if (result !== null) return;
      }
    }
  }
  findInNodes(treeData.value, node.parentId);
  return result || [];
};

const handleMoveSort = async (record, direction) => {
  const siblings = findSiblings(record);
  if (!siblings || siblings.length < 2) return;
  
  const index = siblings.findIndex(item => item.id === record.id);
  
  if (direction === 'up' && index > 0) {
    [siblings[index - 1], siblings[index]] = [siblings[index], siblings[index - 1]];
  } else if (direction === 'down' && index < siblings.length - 1) {
    [siblings[index], siblings[index + 1]] = [siblings[index + 1], siblings[index]];
  } else {
      return;
  }
  
  const sortedIds = siblings.map(s => s.id);
  
  try {
    loading.value = true;
    await updateSortOrder(sortedIds);
    message.success('排序已更新');
    treeData.value = [...treeData.value];
  } catch(error) {
    message.error('排序失败，正在恢复原始顺序...');
    if (direction === 'up') {
      [siblings[index - 1], siblings[index]] = [siblings[index], siblings[index - 1]];
    } else {
      [siblings[index], siblings[index + 1]] = [siblings[index + 1], siblings[index]];
    }
  } finally {
    loading.value = false;
  }
};

onMounted(() => {
  fetchTreeData();
});
</script>

<style scoped>
.table-actions-bar {
  display: flex;
  justify-content: space-between;
  margin-bottom: 16px;
}
.text-danger {
  color: #ff4d4f;
}
:deep(.ant-table-bordered .ant-table-thead > tr > th),
:deep(.ant-table-bordered .ant-table-tbody > tr > td) {
  border-color: #f0f0f0;
}
</style>